TITLE 10/05/83 TEST4  POST UTILITIES
.XLIST
INCLUDE DSEG.SRC
INCLUDE POSTEQU.SRC
.LIST
PUBLIC	POST4
PUBLIC	E_MSG
PUBLIC	KBD_RESET
PUBLIC	BEEP
PUBLIC	ERR_BEEP
PUBLIC	E_MSG
PUBLIC	DDS
PUBLIC	P_MSG
PUBLIC	PRT_SEG
PUBLIC	DUMMY_RETURN_1
PUBLIC	D11
PUBLIC	INT_287
PUBLIC	RE_DIRECT

INCLUDE SEGMENT.SRC

EXTRN	PRT_HEX:NEAR
EXTRN	XPC_BYTE:NEAR
EXTRN	XMIT_8042:NEAR
EXTRN	OBF_42:NEAR
ASSUME	CS:CODE,DS:ABS0
POST4:
;----------------------------------------------------------------------
;	THIS SUBROUTINE WILL PRINT A MESSAGE ON THE DISPLAY
;
; ENTRY REQUIREMENTS:
;	SI = OFFSET(ADDRESS) OF MESSAGE BUFFER
;	CX = MESSAGE BYTE COUNT
;	MAXIMUM MESSAGE LENGTH IS 36 CHARACTERS
;----------------------------------------------------------------------
E_MSG	PROC	NEAR
	MOV	BP,SI				; SET BP NON-ZERO TO FLAG ERR
	CALL	P_MSG				; PRINT MESSAGE
	PUSH	DS
ASSUME	DS:DATA
	CALL	DDS
	MOV	AL,BYTE PTR EQUIP_FLAG		; LOOP/HALT ON ERROR
	AND	AL,01H				; SWITCH ON?
	JNZ	NOT_ON				; NO - RETURN
MFG_HALT:
	CLI					; YES - HALT SYSTEM
	MOV	AL,MFG_ERR_FLAG 		; RECOVER ERROR INDICATOR
	OUT	MFG_PORT,AL			; SET INTO MFG PORT
	HLT					; HALT SYS
NOT_ON:
	POP	DS				; WRITE_MSG:
	RET
E_MSG	ENDP
P_MSG	PROC	NEAR
G12A:	MOV	AL,CS:[SI]			; PUT CHAR IN AL
	INC	SI				; POINT TO NEXT CHAR
	PUSH	AX				; SAVE PRINT CHAR
	CALL	PRT_HEX 			; CALL VIDEO_IO
	POP	AX				; RECOVER PRINT CHAR
	CMP	AL,10				; WAS IT LINE FEED?
	JNE	G12A				; NO,KEEP PRINTING STRING
	RET
P_MSG	ENDP
;---------------------------------------------
;  INITIAL RELIABILITY TEST -- SUBROUTINES
;---------------------------------------------
	ASSUME	 CS:CODE,DS:DATA
;------------------------------------------------------------------------
;	SUBROUTINES FOR POWER ON DIAGNOSTICS
;------------------------------------------------------------------------
;	THIS PROCEDURE WILL ISSUE ONE LONG TONE (3 SECS) AND ONE OR
;	MORE SHORT TONES (1 SEC) TO INDICATE A FAILURE ON THE PLANAR
;	BOARD, A BAD RAM MODULE, OR A PROBLEM WITH THE CRT.
; ENTRY PARAMETERS:
;	DH = NUMBER OF LONG TONES TO BEEP
;	DL = NUMBER OF SHORT TONES TO BEEP.
;------------------------------------------------------------------------
ERR_BEEP PROC	NEAR
	PUSHF					; SAVE FLAGS
	CLI					; DISABLE SYSTEM INTERRUPTS
	PUSH	DS				; SAVE DS REG CONTENTS
	CALL	DDS
	OR	DH,DH		; ANY LONG ONES TO BEEP
	JZ	G3		; NO, DO THE SHORT ONES
G1:				; LONG_BEEP:
	MOV	BL,6		; COUNTER FOR BEEPS
	CALL	BEEP		; DO THE BEEP
G2:	LOOP	G2		; DELAY BETWEEN BEEPS
	DEC	DH		; ANY MORE TO DO
	JNZ	G1		; DO IT
	CMP	MFG_TST,1	; MFG TEST MODE?
	JNE	G3		; YES - CONTINUE BEEPING SPEAKER
	JMP	MFG_HALT	; STOP BLINKING LED
G3:				; SHORT_BEEP:
	MOV	BL,1		; COUNTER FOR A SHORT BEEP
	CALL	BEEP		; DO THE SOUND
G4:	LOOP	G4		; DELAY BETWEEN BEEPS
	DEC	DL		; DONE WITH SHORTS
	JNZ	G3		; DO SOME MORE
G5:	LOOP	G5		; LONG DELAY BEFORE RETURN
G6:	LOOP	G6
	POP	DS		; RESTORE ORIG CONTENTS OF DS
	POPF			; RESTORE FLAGS TO ORIG SETTINGS
	RET			; RETURN TO CALLER
ERR_BEEP	ENDP

;	ROUTINE TO SOUND THE BEEPER

BEEP	PROC	NEAR
	MOV	AL,10110110B			; SEL TIM 2,LSB,MSB,BINARY
	OUT	TIMER+3,AL			; WRITE THE TIMER MODE REG
	JMP	SHORT $+2			; IO DELAY
	MOV	AX,533H 			; DIVISOR FOR 896 HZ
	OUT	TIMER+2,AL			; WRITE TIMER 2 CNT - LSB
	JMP	SHORT $+2			; IO DELAY
	MOV	AL,AH
	OUT	TIMER+2,AL			; WRITE TIMER 2 CNT - MSB
	IN	AL,PORT_B			; GET CURRENT SETTING OF PORT
	MOV	AH,AL				; SAVE THAT SETTING
	JMP	SHORT $+2			; IO DELAY
	OR	AL,03				; TURN SPEAKER ON
	OUT	PORT_B,AL
	SUB	CX,CX				; SET CNT TO WAIT 500 MS
G7:	LOOP	G7				; DELAY BEFORE TURNING OFF
	DEC	BL				; DELAY CNT EXPIRED?
	JNZ	G7				; NO - CONTINUE BEEPING SPK

	MOV	AL,AH				; RECOVER VALUE OF PORT
	OUT	PORT_B,AL
	RET					; RETURN TO CALLER
BEEP	ENDP


;------------------------------------------------------------------------
;	THIS PROCEDURE WILL SEND A SOFTWARE RESET TO THE KEYBOARD.
;	SCAN CODE 'AA' SHOULD BE RETURNED TO THE CPU.
;	SCAN CODE '65' IS DEFINED FOR MANUFACTURING TEST
;------------------------------------------------------------------------
KBD_RESET	PROC	NEAR
	MOV	AL,0FFH 		; SET KEYBOARD RESET COMMAND
	CALL	XMIT_8042		; GO ISSUE THE COMMAND
	JCXZ	G13			; GO IF ERROR

	CMP	AL,KB_ACK		;
	JNZ	G13

	MOV	AL,0FDH 		; ENABLE KEYBOARD INTERRUPTS
	OUT	INTA01,AL		; WRITE 8259 IMR
	MOV	INTR_FLAG,0		; RESET INTERRUPT INDICATOR
	STI				; ENABLE INTERRUPTS

	MOV	BL,10			; TRY FOR 400 MSEC
	SUB	CX,CX			; SETUP INTERRUPT TIMEOUT CNT
G11:	TEST	INTR_FLAG,02H		; DID A KEYBOARD INTR OCCUR?
	JNZ	G12			; YES - READ SCAN CODE RETURNED
	LOOP	G11			; NO - LOOP TILL TIMEOUT
	DEC	BL			;
	JNZ	G11			; TRY AGAIN

G12:	IN	AL,PORT_A		; READ KEYBOARD SCAN CODE
	MOV	BL,AL			; SAVE SCAN CODE JUST READ
G13:	RET				; RETURN TO CALLER
KBD_RESET	ENDP

DDS	PROC	NEAR
	PUSH	AX
	MOV	AX,DATA
	MOV	DS,AX
	POP	AX
	RET
DDS	ENDP

;--------------------------------------------------------
; TEMPORARY INTERRUPT SERVICE ROUTINE			:
;	1. THIS ROUTINE IS ALSO LEFT IN PLACE AFTER THE :
;	POWER ON DIAGNOSTICS TO SERVICE UNUSED		:
;	INTERRUPT VECTORS. LOCATION 'INTR_FLAG' WILL    :
;	CONTAIN EITHER: 1. LEVEL OF HARDWARE INT. THAT	:
;	CAUSED CODE TO BE EXEC. 			:
;	2. 'FF' FOR NON-HARDWARE INTERRUPTS THAT WAS    :
;	EXECUTED ACCIDENTLY.				:
;--------------------------------------------------------
D11	PROC	NEAR
	ASSUME	DS:DATA
	PUSH	DS
	PUSH	DX
	PUSH	AX			; SAVE REG AX CONTENTS
	PUSH	BX
	CALL	DDS			; SET DATA SEGMENT
	MOV	AL,0BH			; READ IN-SERVICE REG
	OUT	INTA00,AL		; (FIND OUT WHAT LEVEL BEING
	JMP	SHORT $+2		; IO DELAY
	NOP				; SERVICED)
	IN	AL,INTA00		; GET LEVEL
	MOV	AH,AL			; SAVE IT
	OR	AL,AH			; 00? (NO HARDWARE ISR ACTIVE)
	JNZ	HW_INT
	MOV	AH,0FFH
	JMP	SHORT SET_INTR_FLAG	; SET FLAG TO FF IF NON-HDWARE
HW_INT:
	MOV	AL,0BH			;
	OUT	INTB00,AL		; READ IN-SERVICE REGISTER FROM
	JMP	SHORT $+2		; IO DELAY
	IN	AL,INTB00		; CHECK THE SECOND INT CHIP
	MOV	BH,AL			; SAVE IT
	OR	BH,BH			;
	JZ	NOT_SEC 		; CONTINUE IF NOT
	IN	AL,INTB01		; GET SECOND INTERRUPT MASK
	OR	AL,BH			; MASK OFF LVL BEING SERVICED
	JMP	SHORT $+2		; IO DELAY
	OUT	INTB01,AL		;
	MOV	AL,EOI			; SEND EOI TO SECOND CHIP
	JMP	SHORT $+2		; IO DELAY
	OUT	INTB00,AL		;
NOT_SEC:IN	AL,INTA01		; GET CURRENT MASK VALUE
	JMP	SHORT $+2		; IO DELAY
	OR	AL,AH			; MASK OFF LVL BEING SERVICED
	OUT	INTA01,AL
	JMP	SHORT $+2		; IO DELAY
	MOV	AL,EOI
	OUT	INTA00,AL
SET_INTR_FLAG:
	MOV	INTR_FLAG,AH		; SET FLAG
	POP	BX
	POP	AX			; RESTORE REG AX CONTENTS
	POP	DX
	POP	DS
DUMMY_RETURN_1: 			; NEED IRET FOR VECTOR TABLE
	IRET
D11	ENDP


;--HARDWARE INT 13 (LEVEL 75) ---------------------------
; SERVICE X287 INTERRUPTS				:
;	THIS ROUTINE FIELDS X287 INTERRUPTS AND CONTROL :
;	IS PASSED TO THE NMI INTERRUPT HANDLER FOR	:
;	COMPATIBILITY.					:
;							:
;--------------------------------------------------------

INT_287 PROC	NEAR
	PUSH	AX			; SAVE AX
	XOR	AL,AL			;
	OUT	X287,AL 		; REMOVE THE INT REQUEST

	MOV	AL,EOI			; ENABLE THE INTERRUPT
	OUT	INTB00,AL		;  THE SLAVE
	OUT	INTA00,AL		;  THE MASTER

	POP	AX			; RESTORE AX
	INT	2			; GIVE CONTROL TO NMI

	IRET				; RETURN
INT_287 ENDP


;--HARDWARE INT 9 (LEVEL 71H) ---------------------------
; REDIRECT SLAVE INTERRUPT 9 TO INTERRUPT LEVEL 2	:
;	THIS ROUTINE FIELDS LEVEL 9 INTERRUPTS AND	:
;	CONTROL IS PASSED TO MASTER INTERRUPT LEVEL 2	:
;--------------------------------------------------------

RE_DIRECT PROC	NEAR
	PUSH	AX			; SAVE AX
	MOV	AL,EOI
	OUT	INTB00,AL		; EOI TO SLAVE INT CONTROLLER
	POP	AX			; RESTORE AX
	INT	0AH			; GIVE CONTROL TO HARDWARE LEVEL 2

	IRET				; RETURN
RE_DIRECT ENDP
;----------------------------------------------------------------
;	PRINT A SEGMENT VALUE TO LOOK LIKE A 21 BIT ADDRESS	 :
;	DX MUST CONTAIN SEGMENT VALUE TO BE PRINTED		 :
;----------------------------------------------------------------
PRT_SEG PROC	NEAR
	MOV	AL,DH			;GET MSB
	CALL	XPC_BYTE		;
	MOV	AL,DL			;LSB
	CALL	XPC_BYTE		;
	MOV	AL,'0'                  ; PRINT A '0 '
	CALL	PRT_HEX 		;
	MOV	AL,' '                  ;SPACE
	CALL	PRT_HEX 		;
	RET				;
PRT_SEG ENDP
CODE	ENDS
	END
